﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace WebTest
{
    public partial class UploadCert : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }

        protected void upload_Click(object sender, EventArgs e)
        {
            string url = "http://demo.comm01.com/pushmanager/project/add";

            if (rbServer.SelectedValue == "1")
            {
                url = "http://localhost/pushmanager/project/add";
            }

            NameValueCollection nvc = new NameValueCollection();
            nvc.Add("appName", txtAppName.Text);
            //nvc.Add("senderId", "projectnumber");
            //nvc.Add("AuthorizationToken", "token");
            //nvc.Add("packageName", "packName");

            nvc.Add("password", txtPwd.Text);
            nvc.Add("SandBoxPassWord", sandboxPwd.Text);

            var path = Server.MapPath("~/CertUrl");
            var sandboxPath = Server.MapPath("~/sandbox_certUrl");
            file1.PostedFile.SaveAs(path);
            fileSandBox.PostedFile.SaveAs(sandboxPath);

            FileInfoCollection fic = new FileInfoCollection();
            fic.FileInfos.Add(new FileInfo(path, "CertUrl", "application/x-pkcs12"));
            fic.FileInfos.Add(new FileInfo(sandboxPath, "sandbox_certUrl", "application/x-pkcs12"));

            //var result = HttpUploadFile(url, nvc, fic);

            var files = new string[] { path, sandboxPath };
            var result = HttpUploadFile(url, fic, nvc);
            lblResult.Text = result;
            if (File.Exists(path))
                File.Delete(path);
            if (File.Exists(sandboxPath))
                File.Delete(sandboxPath);
        }

        public class FileInfo
        {
            public FileInfo(string filepath, string fileName, string contentType)
            {
                this.filePath = filepath;
                this.fileName = fileName;
                this.contentType = contentType;
            }
            public string fileName { get; set; }
            public string filePath { get; set; }
            public string contentType { get; set; } = "content/application/octet-stream";
        }

        public class FileInfoCollection
        {
            public FileInfoCollection()
            {
                FileInfos = new List<FileInfo>();
            }
            public List<FileInfo> FileInfos { get; set; }
        }

        #region 6.0 上传多个文件和参数
        /// <summary>
        /// HttpUploadFile
        /// </summary>
        /// <param name="url"></param>
        /// <param name="files"></param>
        /// <param name="data"></param>
        /// <param name="encoding"></param>
        /// <returns></returns>
        public static string HttpUploadFile(string url, FileInfoCollection fic, NameValueCollection data)
        {
            //必须
            string boundary = DateTime.Now.Ticks.ToString("X");
            //必须的

            //form 开始标志
            byte[] boundarybytes = Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n");

            //form 结尾标志
            byte[] endbytes = Encoding.ASCII.GetBytes("\r\n--" + boundary + "--\r\n");

            //1.HttpWebRequest
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);

            request.ContentType = "multipart/form-data;charset=utf-8;boundary=" + boundary;
            request.Method = "POST";
            request.KeepAlive = true;
            request.Credentials = CredentialCache.DefaultCredentials;

            using (Stream stream = request.GetRequestStream())
            {
                //传递参数模板 Content-Disposition:form-data;name=\"{0}\"\r\n\r\n{1}
                //1.1 key/value
                string formdataTemplate = "Content-Disposition:form-data;name=\"{0}\"\r\n\r\n{1}";
                //传递参数
                if (data != null)
                {
                    foreach (string key in data.Keys)
                    {
                        //传递参数开始标识
                        stream.Write(boundarybytes, 0, boundarybytes.Length);

                        string formitem = string.Format(formdataTemplate, key, data[key]);

                        byte[] formitembytes = Encoding.UTF8.GetBytes(formitem);

                        stream.Write(formitembytes, 0, formitembytes.Length);
                    }
                }

                //上传文件模板
                //1.2 file
                string headerTemplate = "Content-Disposition:form-data;name=\"{0}\";filename=\"{1}\"\r\nContent-Type:{2}\r\n\r\n";

                byte[] buffer = new byte[6 * 1024 * 1024];

                foreach (var f in fic.FileInfos)
                {
                    var filename = f.fileName;
                    var filepath = f.filePath;
                    stream.Write(boundarybytes, 0, boundarybytes.Length);

                    string header = string.Format(headerTemplate, filename, filepath, f.contentType);

                    byte[] headerbytes = Encoding.UTF8.GetBytes(header);

                    stream.Write(headerbytes, 0, headerbytes.Length);

                    //将文件流读入到请求流中
                    using (FileStream fileStream = new FileStream(filepath, FileMode.Open, FileAccess.Read))
                    {
                        int r = fileStream.Read(buffer, 0, buffer.Length);
                        stream.Write(buffer, 0, r);
                    }

                }

                //form 结束标志
                //1.3 form end
                stream.Write(endbytes, 0, endbytes.Length);
            }
            //2.WebResponse
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            using (StreamReader stream = new StreamReader(response.GetResponseStream()))
            {

                string result = stream.ReadToEnd();
                return result;
            }
        }

        #endregion
    }
}